package com.cowealth.platform.common.web.jackson;

import com.cowealth.platform.common.base.jackson.CustomBeanSerializerModifier;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.lang.Nullable;

import java.io.IOException;

/**
 * 继承自定义的SpringMvc的抽象json处理器，SpringMvc默认实现为
 * {@link MappingJackson2HttpMessageConverter}
 *
 * 针对 api 服务对 android 和 ios 和 web 处理的 分读写的 jackson 处理
 *
 * <p>
 * 1. app 端上报数据是 使用 readObjectMapper
 * 2. 返回给 app 端的数据使用 writeObjectMapper
 * </p>
 *
 * @author : skycdm
 * @version : 1.0.0
 * @date : 2021/4/25 10:29
 */
public class MappingApiJackson2HttpMessageConverter extends AbstractReadWriteJackson2HttpMessageConverter{

    @Nullable
    private String jsonPrefix;


    /**
     * 默认实现，和SpringMvc无区别
     * Construct a new {@link MappingApiJackson2HttpMessageConverter} using default configuration
     * provided by {@link Jackson2ObjectMapperBuilder}.
     */
    public MappingApiJackson2HttpMessageConverter() {
        this(Jackson2ObjectMapperBuilder.json().build());
    }

    /**
     * 存在ObjectMapper的自定义
     * Construct a new {@link MappingApiJackson2HttpMessageConverter} with a custom {@link ObjectMapper}.
     * You can use {@link Jackson2ObjectMapperBuilder} to build it easily.
     * @param objectMapper ObjectMapper
     * @see Jackson2ObjectMapperBuilder#json()
     */
    public MappingApiJackson2HttpMessageConverter(ObjectMapper objectMapper) {
        super(objectMapper, initWriteObjectMapper(objectMapper), MediaType.APPLICATION_JSON, new MediaType("application", "*+json"));
    }

    /**
     * 核心处理
     *
     * @param readObjectMapper
     * @return
     */
    private static ObjectMapper initWriteObjectMapper(ObjectMapper readObjectMapper) {
        // 拷贝 readObjectMapper
        ObjectMapper writeObjectMapper = readObjectMapper.copy();
        // null 处理
        writeObjectMapper.setSerializerFactory(writeObjectMapper.getSerializerFactory().withSerializerModifier(new CustomBeanSerializerModifier()));
        writeObjectMapper.getSerializerProvider().setNullValueSerializer(CustomBeanSerializerModifier.NullJsonSerializers.STRING_JSON_SERIALIZER);
        return writeObjectMapper;
    }


    public void setJsonPrefix(String jsonPrefix) {
        this.jsonPrefix = jsonPrefix;
    }

    public void setPrefixJson(boolean prefixJson) {
        this.jsonPrefix = prefixJson ? ")]}', " : null;
    }

    @Override
    protected void writePrefix(JsonGenerator generator, Object object) throws IOException {
        if (this.jsonPrefix != null) {
            generator.writeRaw(this.jsonPrefix);
        }

    }
}
